package org.ihelpuoo.weboo.module;

import java.util.Iterator;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.ihelpuoo.I;
import org.ihelpuoo.io.FileUtils;
import org.ihelpuoo.lang.ExceptionUtils;
import org.ihelpuoo.lang.NutException;
import org.ihelpuoo.parser.segment.CharSegment;
import org.ihelpuoo.parser.segment.Segment;
import org.ihelpuoo.util.Stopwatch;
import org.ihelpuoo.weboo.Weboo;
import org.ihelpuoo.weboo.WebooUtils;
import org.ihelpuoo.weboo.bean.ModuleBean;
import org.ihelpuoo.weboo.exception.ModuleNotFoundException;

/**
 * <b>WebooServlet class:</b>
 * <hr color=grey size=1>
 *
 * Got one param as the action mapping file
 *
 * @author zozoh  created @ 2006
 *
 */
public class WebooActionServlet extends WebooServlet
{
	private static final long	serialVersionUID	= -2514096499273255483L;
	private Logger				log					= Logger.getLogger(WebooActionServlet.class);

	@Override
	public void init() throws ServletException
	{
		super.init();

		Stopwatch sw = new Stopwatch();
		if (log.isInfoEnabled())
			log.info("Launching " + Weboo.NAME + "...");
		sw.start();

		try
		{
			if (log.isInfoEnabled())
				log.info("Install modules <" + Weboo.MODULE_FILE_NAME + ">");

			ModuleMusterFile mmf = new ModuleMusterFile(FileUtils.findFile(getServletContext()
					.getRealPath("/WEB-INF/module_muster")));

			if (log.isInfoEnabled())
				log.info(mmf.getLicenceInfo());

			Iterator<String> it = mmf.iterator();
			ModuleBean defaultBean = null;
			while (it.hasNext())
			{
				Segment moduleFileName = new CharSegment(it.next());
				moduleFileName.set("appRoot",webooConfig.getRootPath());
				try
				{
					ModuleBean loaderBean = new ModuleBean();
					loaderBean = (ModuleBean)webooConfig.pojo().fetchByXMLFileName(
							moduleFileName.toString(),loaderBean,null,null);
					if (null == loaderBean)
					{
						if (log.isInfoEnabled())
							log.info("[Failed] -> " + moduleFileName);
						continue;
					}
					if (defaultBean == null)
						defaultBean = loaderBean;
					else
						loaderBean.mergeWith(defaultBean);

					ModuleLoader loader = new ModuleLoader(webooConfig,loaderBean);

					ModuleContext mc = new ModuleContext(nut,moduleManager,webooConfig);
					Module m = moduleManager.loadModule(loader,mc);

					if (log.isInfoEnabled())
						log.info("[OK] " + m.getName() + " loaded.");
				}
				catch (Exception e)
				{
					log.warn(ExceptionUtils.dump(e));
				}
			}
			if (null != defaultBean)
			{
				moduleManager.setDefaultModule(moduleManager.getModule(defaultBean.getName()));
				if (log.isInfoEnabled())
					log.info("<default-module> => " + moduleManager.getDefaultModule().getName());
			}
			moduleManager.sortLocales();

			if (log.isInfoEnabled())
			{
				log.info("# Process installation ... ");
			}

			Iterator<Module> mit = moduleManager.modules.values().iterator();
			while (mit.hasNext())
			{
				Module m = mit.next();
				if (log.isDebugEnabled())
				{
					log.debug("[" + m.getName() + "]");
					log.debug("Merge actions ...");
				}
				if (m.getActionManager() != null)
					m.getActionManager().mergeAllActionsWithParents();

				ModuleInstaller installer = m.getInstaller();
				if (null != installer)
					installer.install(m.getModuleContext());

				if (log.isDebugEnabled())
					log.debug("OK");
			}
		}
		catch (Exception e)
		{
			log.error(ExceptionUtils.dump(e));
		}
		if (log.isDebugEnabled())
			log.debug(I.NEW_LINE + moduleManager.toString());
		sw.stop();
		if (log.isInfoEnabled())
			log.info("[OK] " + Weboo.NAME + " up in " + sw.getTimeInMillis() + "ms");
	}

	@Override
	public void destroy()
	{
		try
		{
			this.webooConfig.depose();
		}
		catch (NutException e)
		{
			log.error(ExceptionUtils.dump(e));
		}
		if (log.isInfoEnabled())
			log.info("[OK] " + Weboo.NAME + " shutdown!");
	}

	@Override
	protected void doHTTP(HttpServletRequest request, HttpServletResponse response)
	{
		super.doHTTP(request,response);
		try
		{
			String path = request.getServletPath();
			StringBuffer sb = new StringBuffer();
			int i = WebooUtils.getModuleNameFromPath(path,sb);
			Module m = moduleManager.getModule(sb.toString());
			sb = new StringBuffer();
			for (i++; i < path.length(); i++)
			{
				char c = path.charAt(i);
				if ('.' == c)
					break;
				sb.append(c);
			}
			m.processAction(sb.toString(),moduleManager.getControllers(m.getName()),request,
					response);

		}
		catch (ModuleNotFoundException e)
		{
			response.setStatus(404);
			log.warn(ExceptionUtils.dumpBrief(e));
		}
		catch (Exception e)
		{
			log.error(ExceptionUtils.dump(e));
		}

	}
}
